package com.ht.module.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ht.abnormal.HtException;
import com.ht.config.dataAuth.DataScope;
import com.ht.constant.BusConstant;
import com.ht.constant.RedisConstants;
import com.ht.module.sys.entity.SysDept;
import com.ht.module.sys.mapper.SysDeptMapper;
import com.ht.module.sys.service.ISysDeptService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ht.util.CommMethod;
import com.ht.util.RedisUtil;
import com.ht.util.UserUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 部门表 服务实现类
 * </p>
 *
 * @author hejialun
 * @since 2022-04-18
 */
@Service
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements ISysDeptService {
    @Resource
    private RedisUtil redisUtil;

    @Override
    public List<Tree<String>> findSubsetById(String id) {
        List<Tree<String>> trees = this.findTree(new SysDept());
        //找到当前节点
        Tree<String> node = null;
        for (Tree<String> tree : trees) {
            node = TreeUtil.getNode(tree, id);
        }
        //定义子集
        List<Tree<String>> subset = new ArrayList<>();

        if (node != null) {
            //找到了节点递归遍历当前节点获取所有子节点
            ergodicNode(node.getChildren(), subset);
        }
        return subset;
    }


    private void ergodicNode(List<Tree<String>> children, List<Tree<String>> subset) {
        for (Tree<String> child : children) {
            subset.add(child);
            if (child.getChildren() != null && child.getChildren().size() > 0) {
                //递归
                ergodicNode(child.getChildren(), subset);
            }
        }
    }


    @Override
    public List<Tree<String>> findTree(SysDept en) {
        QueryWrapper<SysDept> qw = getQW(en);
        List<SysDept> list = baseMapper.findList(qw);
        return buildTree(list);
    }

    @Override
    public List<Tree<String>> findTreeAuth(SysDept en) {
        QueryWrapper<SysDept> qw = getQW(en);
        //获取缓存
        List<Tree<String>> tree = (List<Tree<String>>) redisUtil.get(RedisConstants.DEPT_AUTH_CACHE+ UserUtil.getUserId());
        if (BeanUtil.isNotEmpty(tree)) {
            return tree;
        }
        List<SysDept> list = baseMapper.findListAuth(qw, new DataScope());
        List<Tree<String>> trees = buildTree(list);
        //缓存当前用户的权限信息
        if(en.getIsCache()){
            redisUtil.set(RedisConstants.DEPT_AUTH_CACHE+ UserUtil.getUserId(),trees);
        }
        return buildTree(list);
    }

    private QueryWrapper<SysDept> getQW(SysDept en) {
        QueryWrapper<SysDept> qw = new QueryWrapper<>();
        if (StrUtil.isNotEmpty(en.getDeptCode())) {
            qw.eq("tab.dept_code", en.getDeptCode());
            en.setIsCache(false);
            redisUtil.del(RedisConstants.DEPT_AUTH_CACHE+UserUtil.getUserId());

        }
        if (StrUtil.isNotEmpty(en.getDeptName())) {
            qw.eq("tab.dept_name", en.getDeptName());
            en.setIsCache(false);
            redisUtil.del(RedisConstants.DEPT_AUTH_CACHE+UserUtil.getUserId());
        }
        if (StrUtil.isNotEmpty(en.getDistrictCode())) {
            qw.eq("tab.district_code", en.getDistrictCode());
            en.setIsCache(false);
            redisUtil.del(RedisConstants.DEPT_AUTH_CACHE+UserUtil.getUserId());
        }
        qw.eq("tab.del_flag", BusConstant.DEL_FLAG_N);
        qw.orderByAsc("tab.sort");
        return qw;
    }


    @Override
    public void delById(String id) {
        //判断是否有子集
        if (baseMapper.selectCount(
                new QueryWrapper<SysDept>()
                        .eq("parent_id", id)
        ) > 0) {
            throw new HtException("当前部门，还有子集不可删除！");
        }
        baseMapper.deleteById(id);
        //清除缓存
        redisUtil.delPrefix(RedisConstants.DEPT_AUTH_CACHE);
    }

    @Override
    public void add(SysDept en) {
        if (StrUtil.isEmpty(en.getParentId())) {
            en.setParentId("0");
        }
        baseMapper.insert(en);
        //清除缓存
        redisUtil.delPrefix(RedisConstants.DEPT_AUTH_CACHE);
    }

    @Override
    public void editById(SysDept en) {
        if (StrUtil.isEmpty(en.getParentId())) {
            en.setParentId("0");
        }
        baseMapper.updateById(en);
        //清除缓存
        redisUtil.delPrefix(RedisConstants.DEPT_AUTH_CACHE);
    }


    /**
     * @param depts
     * @return java.util.List<com.ht.module.sys.entity.SysDept>
     * @Author hejialun
     * @Date 16:28 2022/4/18
     * @Description TODO(构建部门树)
     */
    private List<Tree<String>> buildTree(List<SysDept> depts) {
        //构建数据
        for (SysDept dept : depts) {
            dept.setParentIdTemp(dept.getParentId());
            //判断当前数据是否能找到对应的上级id
            SysDept pdept = depts.stream().filter(x -> StrUtil.equals(dept.getParentId(), x.getDeptId())).findFirst().orElse(null);
            if (pdept == null) {
                //没有父id设置为0，顶级节点
                dept.setParentIdTemp("0");
            }
        }
        //构建树配置
        TreeNodeConfig config = new TreeNodeConfig();
        config.setIdKey("deptId");
        config.setParentIdKey("parentIdTemp");
        //定义转换器
        List<Tree<String>> build = TreeUtil.build(depts, "0", config, (node, tree) -> {
            tree.setId(node.getDeptId());
            tree.setParentId(node.getParentId());
            tree.setName(node.getDeptName());
            CommMethod.initExtra(node, tree);
        });
        return build;
    }


}
